package com.hub.netty.client.config;

import com.hub.netty.base.config.NettyProperties;
import io.netty.channel.Channel;
import lombok.RequiredArgsConstructor;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @ author 令狐冲
 * @ date & time 2025/2/19 16:04
 */
@RequiredArgsConstructor
public class NettyChannelPool {

    private final NettyChannelFactory channelFactory;

    private final NettyProperties nettyProperties;

    private final BlockingQueue<Channel> pool = new LinkedBlockingQueue<>();

    /**
     * 从池中获取Channel
     */
    public Channel borrowChannel() {
        Channel channel = pool.poll();
        if (channel != null && channel.isActive()) {
            return channel;
        }
        channel = channelFactory.createChannel(nettyProperties.getHost(), nettyProperties.getPort());

        return channel;
    }

    /**
     * 归还Channel到池中
     */
    public void returnChannel(Channel channel) {
        if (channel != null && channel.isActive() && pool.size() < nettyProperties.getWorker()) {
            pool.offer(channel);
        } else {
            assert channel != null;
            channel.close();
        }
    }

    /**
     * 关闭连接池
     */
    public void shutdown() {
        channelFactory.shutdown();
        pool.forEach(Channel::close);
        pool.clear();
    }
}
